package fuzion24.device.vulnerability.vulnerabilities.system;

import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import java.lang.Thread;
import java.util.ArrayList;
import java.util.List;

import android.os.Build;

import fuzion24.device.vulnerability.util.CPUArch;
import fuzion24.device.vulnerability.vulnerabilities.VulnerabilityTest;

public class SamsungCREDzip implements VulnerabilityTest {

    private final static int BUFFER_SIZE = 1024;
    private final static String DESTINATION = "/sdcard/Download/";
    private final static String FILENAME = "cred.zip";
    private final static String ASSETNAME = "Samsung_cred.zip";


    @Override
    public List<CPUArch> getSupportedArchitectures() {
        ArrayList<CPUArch> archs = new ArrayList<>();
        archs.add(CPUArch.ALL);
        return archs;
    }

    @Override
    public String getCVEorID() {
        return "CVE-2015-7888";
    }

    private boolean thisHasSDCardPermission(Context ctx)
    {
        String readPermission = "android.permission.READ_EXTERNAL_STORAGE";
        String writePermission = "android.permission.WRITE_EXTERNAL_STORAGE";
        return (ctx.checkCallingOrSelfPermission(readPermission) == PackageManager.PERMISSION_GRANTED && 
                ctx.checkCallingOrSelfPermission(writePermission) == PackageManager.PERMISSION_GRANTED);
    }
    
    private boolean isSamsungPhone(){
        return Build.MANUFACTURER.equals("samsung");
    }
    
    @Override
    public boolean isVulnerable(Context context) throws Exception {
        boolean isVuln = false;
        
        if(!isSamsungPhone()) return false;
        
        if(!thisHasSDCardPermission(context))
            throw new Exception("No SDCard permission assigned to app to perform Samsung cred.zip remote code execution test");

        InputStream in = null;
        OutputStream out = null;
        try{
            AssetManager assetFiles = context.getAssets();
            File outFile = new File(DESTINATION, FILENAME);
            in = assetFiles.open(ASSETNAME);
            out = new FileOutputStream(outFile);
            
            byte[] buffer = new byte[BUFFER_SIZE];
            int read;
            while((read = in.read(buffer)) != -1){
                out.write(buffer, 0, read);
            }

            Thread.sleep(3000);
         
            outFile = null;
            outFile = new File(DESTINATION, FILENAME);
            if(outFile.exists()){
                isVuln = false;
                outFile.delete();
            }else{
                isVuln = true;
            }
        }catch(IOException e){
            throw new Exception("Error when extracting the asset file: " + e);
        }finally{
            if (in != null)
                in.close();
            if (out != null)
                out.close();
        }
        
        return isVuln;
    }
}
